--- title: "I'm the Map Possible Solutions" linktitle: "Week 6: I'm the Map Possible Solutions" output: blogdown::html_page: toc: true menu: assignment: parent: Possible Solutions weight: 6 type: docs weight: 1 editor_options: chunk_output_type: console ---
Remember just because your code doesn’t look like mine doesn’t mean anything. Included are examples of approaches that can be used to complete this task, but there are so many more!
library(tidyverse)
library(tidycensus)
library(DT)
library(wesanderson)
library(ggthemes)
library(scales)
First let’s check the FIPS codes for the states and counties
head(tidycensus::fips_codes)
## state state_code state_name county_code county
## 1 AL 01 Alabama 001 Autauga County
## 2 AL 01 Alabama 003 Baldwin County
## 3 AL 01 Alabama 005 Barbour County
## 4 AL 01 Alabama 007 Bibb County
## 5 AL 01 Alabama 009 Blount County
## 6 AL 01 Alabama 011 Bullock County
For the following, we’ll use a single variable though you can absolutely use many more! In this case, let’s utilize the average income measured by medians in 2016.
vars_of_interest <- c(median_income = "B19013_001")
We will need continuous color palettes to display the data well. In this case we’ll use the wesanderson collection, but please feel free to use your own.
national_data <- get_acs(geography = "county",
variables = vars_of_interest,
year = 2016,
survey = "acs5",
shift_geo = TRUE,
geometry = TRUE) %>%
rename(`Median Income` = estimate)
Make sure to check it
datatable(national_data)
Let’s now create a palette
wes_palette("Darjeeling2")

make it continuous
darj2 <- wes_palette("Darjeeling2",
max(national_data$`Median Income`,
na.rm = TRUE),
type = "continuous")
and plot it for the entire US
ggplot() +
geom_sf(data = national_data,
mapping = aes(fill = `Median Income`),
color = NA) +
coord_sf(datum = NA) +
scale_fill_gradientn(colors = darj2) +
theme_minimal() +
theme(plot.title = element_text(size = 20,
face = "bold",
color = "#005b5b",
hjust = 0.5)) +
ggtitle(stringr::str_wrap("2016 ACS Median Income for the United States", 35))

Here is a US Census PDF of what the regions are. Now Region 1 can be defined by
region1 = c("CT", "ME", "MA", "NH", "RI", "VT", "NJ", "NY", "PA")
We get acs data and geographies for our variable at the
multistate_tract_data <- get_acs(geography = "tract",
variables = vars_of_interest,
state = region1,
year = 2016,
survey = "acs5",
geometry = TRUE) %>%
rename(`Median Income` = estimate)
Make sure to check it
datatable(multistate_tract_data)
| GEOID | NAME | variable | Median Income | moe | geometry |
|---|---|---|---|---|---|
| 09001011000 | Census Tract 110, Fairfield County, Connecticut | median_income | 248171 | 33760 | MULTIPOLYGON (((-73.58765 4… |
| 09001020800 | Census Tract 208, Fairfield County, Connecticut | median_income | 134934 | 15960 | MULTIPOLYGON (((-73.54896 4… |
| 09001021400 | Census Tract 214, Fairfield County, Connecticut | median_income | 55101 | 7886 | MULTIPOLYGON (((-73.56834 4… |
| 09001022200 | Census Tract 222, Fairfield County, Connecticut | median_income | 58889 | 10637 | MULTIPOLYGON (((-73.54503 4… |
| 09001043100 | Census Tract 431, Fairfield County, Connecticut | median_income | 125536 | 31382 | MULTIPOLYGON (((-73.47108 4… |
| 09001045400 | Census Tract 454, Fairfield County, Connecticut | median_income | 189375 | 38749 | MULTIPOLYGON (((-73.42248 4… |
multistate_state_data <- get_acs(geography = "state",
variables = vars_of_interest,
state = region1,
year = 2016,
survey = "acs5",
geometry = TRUE) %>%
rename(`Median Income` = estimate)
Make sure to check it
datatable(multistate_state_data)
| GEOID | NAME | variable | Median Income | moe | geometry |
|---|---|---|---|---|---|
| 09001011000 | Census Tract 110, Fairfield County, Connecticut | median_income | 248171 | 33760 | MULTIPOLYGON (((-73.58765 4… |
| 09001020800 | Census Tract 208, Fairfield County, Connecticut | median_income | 134934 | 15960 | MULTIPOLYGON (((-73.54896 4… |
| 09001021400 | Census Tract 214, Fairfield County, Connecticut | median_income | 55101 | 7886 | MULTIPOLYGON (((-73.56834 4… |
| 09001022200 | Census Tract 222, Fairfield County, Connecticut | median_income | 58889 | 10637 | MULTIPOLYGON (((-73.54503 4… |
| 09001043100 | Census Tract 431, Fairfield County, Connecticut | median_income | 125536 | 31382 | MULTIPOLYGON (((-73.47108 4… |
| 09001045400 | Census Tract 454, Fairfield County, Connecticut | median_income | 189375 | 38749 | MULTIPOLYGON (((-73.42248 4… |
Putting geometry = TRUE brings in the geographic information (aka shapefiles) so make sure that is on, though if you only need the data and not a map, save yourself some time and turn it off. Geographic data is relatively dense and can take some time depending on how much you need.
Optionally let’s create a palette,
wes_palette("Darjeeling1")

make it continuous
darj1 <- wes_palette("Darjeeling1",
max(multistate_tract_data$`Median Income`,
na.rm = TRUE),
type = "continuous")
and plot it. This is tract level data so you’ll have to wait a little bit
ggplot() +
geom_sf(data = multistate_tract_data,
mapping = aes(fill = `Median Income`),
color = NA) +
scale_fill_gradientn(colors = darj1) +
theme_map()

Let’s give it a go with state borders so its a bit more familiar and with a formatted title and some finagling of the legend
ggplot() +
geom_sf(data = multistate_tract_data,
mapping = aes(fill = `Median Income`),
color = NA) +
geom_sf(data = multistate_state_data,
color = "#f7f7f7",
fill = NA) +
scale_fill_gradientn(colors = darj1,
label = scales::dollar) +
theme_map() +
theme(plot.title = element_text(size = 20,
face = "bold",
color = "#005b5b",
hjust = 0.5),
legend.position = c(0.8,0.1),
legend.title = element_text(size = 12,
face = "bold",
color = "#3392a4",
hjust = 0.5,
margin = margin(b = 10)),
legend.text = element_text(size = 10,
face = "bold",
color = "#2d8292")) +
ggtitle("2016 ACS Median Income for Census Region 1")

We get acs data and geographies for our variable using
state_data <- get_acs(geography = "state",
variables = vars_of_interest,
year = 2016,
survey = "acs5",
shift_geo = TRUE,
geometry = TRUE) %>%
rename(`Median Income` = estimate)
Make sure to check it
datatable(state_data)
Optionally let’s create a palette,
wes_palette("Zissou1")

make it continuous
ziss1 <- wes_palette("Zissou1",
max(state_data$`Median Income`,
na.rm = TRUE),
type = "continuous")
and plot it for the entire US
ggplot() +
geom_sf(data = state_data,
mapping = aes(fill = `Median Income`),
color = NA) +
scale_fill_gradientn(colors = ziss1) +
theme_map() +
theme(plot.title = element_text(size = 20,
face = "bold",
color = "#005b5b",
hjust = 0.5)) +
ggtitle("2016 ACS Median Income for All US States")

or just the lower 48 states
lower_48 <- state_data %>%
filter(GEOID < 60) %>%
filter(!NAME == "Hawaii") %>%
filter(!NAME == "Alaska")
ggplot() +
geom_sf(data = lower_48,
mapping = aes(fill = `Median Income`),
color = NA) +
scale_fill_gradientn(colors = ziss1) +
theme_map() +
coord_sf(crs = 5070,
datum = NA) +
theme(plot.title = element_text(size = 20,
face = "bold",
color = "#005b5b",
hjust = 0.5)) +
ggtitle(stringr::str_wrap("2016 ACS Median Income for the Contiguous US States", 35))

Tract level data is sometimes tricky to get, in that not all data sets with geographies have them. Sticking to the widespread surveys such as the decennial census and acs will always work, while others are up in the air.
kansas <- get_acs(state = "KS",
geography = "county",
variables = vars_of_interest,
geometry = TRUE) %>%
rename(`Median Income` = estimate)
## Getting data from the 2015-2019 5-year ACS
## Downloading feature geometry from the Census website. To cache shapefiles for use in future sessions, set `options(tigris_use_cache = TRUE)`.
##
|
| | 0%
|
|======== | 12%
|
|========= | 12%
|
|========= | 13%
|
|========= | 14%
|
|========== | 14%
|
|========== | 15%
|
|=========== | 15%
|
|=========== | 16%
|
|============ | 17%
|
|============ | 18%
|
|============= | 18%
|
|============= | 19%
|
|============== | 20%
|
|============== | 21%
|
|=============== | 21%
|
|=============== | 22%
|
|================ | 22%
|
|================ | 23%
|
|================= | 24%
|
|================= | 25%
|
|================== | 25%
|
|================== | 26%
|
|=================== | 27%
|
|=================== | 28%
|
|==================== | 28%
|
|==================== | 29%
|
|===================== | 29%
|
|===================== | 30%
|
|===================== | 31%
|
|====================== | 31%
|
|====================== | 32%
|
|======================= | 32%
|
|======================= | 33%
|
|======================== | 34%
|
|======================== | 35%
|
|========================= | 36%
|
|========================== | 36%
|
|========================== | 37%
|
|========================== | 38%
|
|=========================== | 38%
|
|=========================== | 39%
|
|============================ | 39%
|
|============================ | 40%
|
|============================ | 41%
|
|============================= | 41%
|
|============================= | 42%
|
|============================== | 42%
|
|============================== | 43%
|
|=============================== | 44%
|
|=============================== | 45%
|
|================================ | 45%
|
|================================ | 46%
|
|================================= | 47%
|
|================================= | 48%
|
|================================== | 48%
|
|================================== | 49%
|
|=================================== | 49%
|
|=================================== | 50%
|
|=================================== | 51%
|
|==================================== | 51%
|
|==================================== | 52%
|
|===================================== | 52%
|
|===================================== | 53%
|
|====================================== | 54%
|
|======================================= | 55%
|
|======================================= | 56%
|
|======================================== | 56%
|
|======================================== | 57%
|
|======================================== | 58%
|
|========================================= | 58%
|
|========================================= | 59%
|
|========================================== | 59%
|
|========================================== | 60%
|
|=========================================== | 61%
|
|=========================================== | 62%
|
|============================================ | 62%
|
|============================================ | 63%
|
|============================================= | 64%
|
|============================================= | 65%
|
|============================================== | 65%
|
|============================================== | 66%
|
|=============================================== | 67%
|
|=============================================== | 68%
|
|================================================ | 68%
|
|================================================ | 69%
|
|================================================= | 69%
|
|================================================= | 70%
|
|================================================= | 71%
|
|================================================== | 72%
|
|=================================================== | 72%
|
|=================================================== | 73%
|
|==================================================== | 74%
|
|==================================================== | 75%
|
|===================================================== | 75%
|
|===================================================== | 76%
|
|====================================================== | 77%
|
|====================================================== | 78%
|
|======================================================= | 78%
|
|======================================================= | 79%
|
|======================================================== | 80%
|
|======================================================== | 81%
|
|========================================================= | 81%
|
|========================================================= | 82%
|
|========================================================== | 82%
|
|========================================================== | 83%
|
|=========================================================== | 84%
|
|=========================================================== | 85%
|
|============================================================ | 85%
|
|============================================================ | 86%
|
|============================================================= | 86%
|
|============================================================= | 87%
|
|============================================================= | 88%
|
|============================================================== | 88%
|
|============================================================== | 89%
|
|=============================================================== | 89%
|
|=============================================================== | 91%
|
|================================================================ | 91%
|
|================================================================ | 92%
|
|================================================================= | 93%
|
|================================================================== | 94%
|
|================================================================== | 95%
|
|=================================================================== | 95%
|
|=================================================================== | 96%
|
|==================================================================== | 97%
|
|==================================================================== | 98%
|
|===================================================================== | 98%
|
|===================================================================== | 99%
|
|======================================================================| 100%
datatable(kansas)
| GEOID | NAME | variable | Median Income | moe | geometry |
|---|---|---|---|---|---|
| 20099 | Labette County, Kansas | median_income | 47643 | 2802 | MULTIPOLYGON (((-95.52265 3… |
| 20203 | Wichita County, Kansas | median_income | 57978 | 7215 | MULTIPOLYGON (((-101.5671 3… |
| 20077 | Harper County, Kansas | median_income | 49865 | 2945 | MULTIPOLYGON (((-98.3498 37… |
| 20093 | Kearny County, Kansas | median_income | 52599 | 10953 | MULTIPOLYGON (((-101.5419 3… |
| 20069 | Gray County, Kansas | median_income | 64930 | 3363 | MULTIPOLYGON (((-100.665 37… |
| 20161 | Riley County, Kansas | median_income | 51208 | 2475 | MULTIPOLYGON (((-96.96095 3… |
wes_palette("FantasticFox1")

make it continuous
ffox <- wes_palette("FantasticFox1",
max(kansas$`Median Income`,
na.rm = TRUE),
type = "continuous")
and plot it!
kansas %>%
ggplot(aes(fill = `Median Income`)) +
geom_sf(color = NA) +
scale_fill_gradientn(colors = ffox,
label = scales::dollar) +
theme_map() +
theme(legend.position = "bottom",
legend.direction = "horizontal",
legend.title.align=0.5) +
guides(fill = guide_legend(title.position="top")) +
theme(plot.title = element_text(size = 20,
face = "bold",
color = "#005b5b",
hjust = 0.5)) +
ggtitle("2016 ACS Median Income for the Counties in Kansas")

Tract level data is sometimes tricky to get, in that not all data sets with geographies have them. Sticking to the widespread surveys such as the decennial census and acs will always work, while others are up in the air.
doug <- get_acs(state = "KS",
county = "Douglas",
geography = "tract",
variables = vars_of_interest,
geometry = TRUE) %>%
rename(`Median Income` = estimate)
## Getting data from the 2015-2019 5-year ACS
## Downloading feature geometry from the Census website. To cache shapefiles for use in future sessions, set `options(tigris_use_cache = TRUE)`.
##
|
| | 0%
|
|=== | 4%
|
|====== | 8%
|
|======================================================================| 100%
datatable(doug)
| GEOID | NAME | variable | Median Income | moe | geometry |
|---|---|---|---|---|---|
| 20045000901 | Census Tract 9.01, Douglas County, Kansas | median_income | 30353 | 5043 | POLYGON ((-95.26054 38.9359… |
| 20045000502 | Census Tract 5.02, Douglas County, Kansas | median_income | 57035 | 11590 | POLYGON ((-95.2607 38.97286… |
| 20045000501 | Census Tract 5.01, Douglas County, Kansas | median_income | 46952 | 4297 | POLYGON ((-95.261 38.97609,… |
| 20045000604 | Census Tract 6.04, Douglas County, Kansas | median_income | 84536 | 15693 | POLYGON ((-95.2792 38.97794… |
| 20045000300 | Census Tract 3, Douglas County, Kansas | median_income | 28024 | 4766 | POLYGON ((-95.25113 38.9513… |
| 20045000797 | Census Tract 7.97, Douglas County, Kansas | median_income | 64496 | 12992 | POLYGON ((-95.30693 38.957,… |
wes_palette("Cavalcanti1")

make it continuous
caval <- wes_palette("Cavalcanti1",
max(doug$`Median Income`,
na.rm = TRUE),
type = "continuous")
and plot it!
doug %>%
ggplot(aes(fill = `Median Income`)) +
geom_sf(color = NA) +
scale_fill_gradientn(colors = caval,
label = scales::dollar) +
theme_map() +
theme(legend.position = "bottom",
legend.key.width = unit(3, "line")) +
guides(fill = guide_legend(title.position="top",
title.hjust =0.5)) +
theme(plot.title = element_text(size = 20,
face = "bold",
color = "#005b5b",
hjust = 0.5)) +
ggtitle(stringr::str_wrap("2016 ACS Median Income for the Census Tracts in Kansas", 35))
